﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.Collections.Generic;
using Jzy.Workflow.Status.DataService;
using Jzy.Workflow.Status.Code;

namespace Jzy.Workflow.Code
{
    public class FlowNode
    {
        public const double NODE_WIDTH = 75;
        public const double NODE_HEIGHT = 50;
        private List<FlowLine> _lines;

        private Border _border;
        
        /// <summary>
        /// 鼠标位置
        /// </summary>
        private Point _cursorPosition;

        /// <summary>
        /// 按下鼠标时节点的位置
        /// </summary>
        private Point _originalNodePosition;
        private bool _mouseDown;

        private TextBlock _label;

        private NodeType _type;

        public List<FlowLine> Lines
        {
            get
            {
                return _lines;
            }
        }

        public NodeType Type
        {
            get
            {
                return _type;
            }
            set
            {
                _type = value;
                if (_type == NodeType.拟稿 || _type == NodeType.结束)
                {
                    _label.Margin = new Thickness(0, 0, 0, 0);
                    _label.FontSize = 13;
                    _label.VerticalAlignment = VerticalAlignment.Center;
                    this.Width = NODE_WIDTH;
                    this.Height = NODE_HEIGHT;
                    _border.CornerRadius = new CornerRadius(NODE_WIDTH / 2);
                    
                    //this.Name = _type.ToString();
                }
               
            }
        }

        public NodeApproveState ApproveState
        {
            get;
            set;
        }

        public FlowNode(NodeApproveState state)
        {
            ApproveState = state;

            _type = NodeType.常规;
            _lines = new List<FlowLine>();
            _label = new TextBlock();
            _label.TextWrapping = TextWrapping.Wrap;
            _label.TextAlignment = TextAlignment.Center;
            _label.Margin = new Thickness(0, 5, 0, 0);
            if (state == NodeApproveState.已审批)
            {
                _label.Foreground = new SolidColorBrush(Color.FromArgb(0xff, 0x50, 0x50, 0x50));
            }
            else
            {
                _label.Foreground = new SolidColorBrush(FlowColors.Blue);
            }
            _label.FontSize = 12;
            _border = new Border();
            _border.Child = _label;
            _border.BorderThickness = new Thickness(1.5);
            this.Width = 90f;
            this.Height = 55f;

            if (state == NodeApproveState.已审批)
            {
                _border.BorderBrush = new SolidColorBrush(Color.FromArgb(0xff, 0x40, 0x40, 0x40));
            }
            else if (state == NodeApproveState.审批中)
            {
                _border.BorderBrush = new SolidColorBrush(Colors.Red);
            }
            else
            {
                _border.BorderBrush = new SolidColorBrush(FlowColors.Green);
            }
            
            //背景渐变
            LinearGradientBrush brush = new LinearGradientBrush();
            brush.StartPoint = new Point(0.5, 0);
            brush.EndPoint = new Point(0.5, 1);

            GradientStop stop = new GradientStop();
            stop.Color = FlowColors.White;
            stop.Offset = 0;
            brush.GradientStops.Add(stop);

            stop = new GradientStop();
            if (state == NodeApproveState.已审批)
            {
                stop.Color = Color.FromArgb(0xff, 0xaa, 0xaa, 0xaa);
            }
            else
            {
                stop.Color = Color.FromArgb(0xff, 0xc0, 0xd0, 0xc0);
            }
            stop.Offset = 0.6;
            brush.GradientStops.Add(stop);

            stop = new GradientStop();
            if (state == NodeApproveState.已审批)
            {
                stop.Color = Color.FromArgb(0xff, 0x70, 0x70, 0x70);
            }
            else
            {
                stop.Color = FlowColors.Green;
            }
            stop.Offset = 1;
            brush.GradientStops.Add(stop);

            _border.Background = brush;
            _border.CornerRadius = new CornerRadius(3);
            Canvas.SetLeft(_border, 0);
            Canvas.SetTop(_border, 0);

            //if (GlobalVar.ReadOnly == false)
            //{
            //    _border.MouseLeftButtonDown += new MouseButtonEventHandler(_border_MouseLeftButtonDown);
            //    _border.MouseLeftButtonUp += new MouseButtonEventHandler(_border_MouseLeftButtonUp);
            //    _border.MouseMove += new MouseEventHandler(_border_MouseMove);

            //    _border.MouseEnter += new MouseEventHandler(_border_MouseEnter);
            //    _border.MouseLeave += new MouseEventHandler(_border_MouseLeave);
            //}
        }

        public FlowNode(string name,NodeApproveState state)
            : this(state)
        {
            Name = name;
        }

        #region 设置当前活动对象，用于右击事件
        void _border_MouseLeave(object sender, MouseEventArgs e)
        {
            GlobalVar.ActiveElement = null;
            _border.BorderBrush = new SolidColorBrush(FlowColors.Green);
        }

        void _border_MouseEnter(object sender, MouseEventArgs e)
        {
            GlobalVar.ActiveElement = this;
            _border.BorderBrush = new SolidColorBrush(FlowColors.Yellow);
        }
        #endregion

        #region 拖动事件

        void _border_MouseMove(object sender, MouseEventArgs e)
        {
            if (_mouseDown)
            {
                
                this.Left = _originalNodePosition.X + e.GetPosition((UIElement)_border.Parent).X - _cursorPosition.X;
                this.Top = _originalNodePosition.Y + e.GetPosition((UIElement)_border.Parent).Y - _cursorPosition.Y;

                if (this.Left <= 0)
                {
                    this.Left = 0;
                }

                if (this.Top <= 0)
                {
                    this.Top = 0;
                }

                for (int i = 0; i < _lines.Count; i++)
                {
                    _lines[i].Draw();
                }
            }
        }

        void _border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _mouseDown = false;
            _border.ReleaseMouseCapture();

            //保存位置
            FlowSoapClient client = DataFactory.Create();
            client.SaveNodePositionCompleted += new EventHandler<Jzy.Workflow.Status.DataService.SaveNodePositionCompletedEventArgs>(client_SaveNodePositionCompleted);
            client.SaveNodePositionAsync(this.PKID, Left, Top);

        
        }

       

        void client_SaveNodePositionCompleted(object sender, Jzy.Workflow.Status.DataService.SaveNodePositionCompletedEventArgs e)
        {
            bool flag = (bool)e.Result;
            if (flag == false)
            {
                MessageBox.Show("保存位置失败");
            }
        }

        void _border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _mouseDown = true;
            _cursorPosition = e.GetPosition((UIElement)_border.Parent);
            _originalNodePosition = new Point(this.Left, this.Top);
            _border.CaptureMouse();
            Canvas.SetZIndex(_border, GlobalVar.ZIndex);

        }

        #endregion

        public int PKID
        {
            get;
            set;
        }

        /// <summary>
        /// 标题
        /// </summary>
        public string Name
        {
            get
            {
                return _label.Text;
            }
            set
            {
               
                _label.Text = value;
            }
        }

        public Border Node
        {
            get
            {
                return _border;
            }
        }

        public Flow Flow
        {
            get;
            set;
        }

        public double Width
        {
            get
            {
                return _border.Width;
            }
            set
            {
                _border.Width = value;
                _label.Width = value * 0.8;
            }
        }

        public double Height
        {
            get
            {
                return _border.Height;
            }
            set
            {
                _border.Height = value;
            }
        }

        public double Top
        {
            get
            {
                return Canvas.GetTop(_border);
            }
            set
            {
                Canvas.SetTop(_border, value);
            }
        }

        public double Left
        {
            get
            {
                return Canvas.GetLeft(_border);
            }
            set
            {
                Canvas.SetLeft(_border, value);
            }
        }


        public static FlowNode Parse(string xml, NodeApproveState state)
        {
            XElement root = XElement.Parse(xml);
            return Parse(root, state);
        }

        public static FlowNode Parse(XElement xml, NodeApproveState state)
        {
            FlowNode node = new FlowNode(state);
            node.PKID = int.Parse(xml.Element("ID").Value);
            node.Name = xml.Element("Name").Value;
            node.Left = double.Parse(xml.Element("Left").Value);
            node.Top = double.Parse(xml.Element("Top").Value);
            node.Width = double.Parse(xml.Element("Width").Value);
            node.Height = double.Parse(xml.Element("Height").Value);
            node.Type = (NodeType)int.Parse(xml.Element("TypeID").Value);

            return node;
        }

        
        /// <summary>
        /// 矩形中心的位置       
        /// </summary>
        public Point CenterPosition
        {
            get
            {
                return new Point(Left + Width / 2, Top + Height / 2);
            }
        }


        public override bool Equals(object obj)
        {
            if (((FlowNode)obj).PKID == this.PKID)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public override int GetHashCode()
        {
            return this.PKID;
        }
    }
}
